#include "mesh_renderer.h"
#include "teflon/core/asset.h"
#include <glm/glm.hpp>
#include <iostream>

namespace teflon
{
    MeshRenderer::MeshRenderer()
    {
        std::map<teflon::ShaderType, std::string> shader_sources;
        std::string vspath = get_asset_path("shaders/mesh.vs");
        std::string fspath = get_asset_path("shaders/mesh.fs");
        shader_sources.insert(std::make_pair(teflon::ShaderType::Vertex, vspath));
        shader_sources.insert(std::make_pair(teflon::ShaderType::Fragment, fspath));
        shader = std::make_shared<ShaderProgram>(shader_sources);
    }

    MeshRenderer::~MeshRenderer()
    {
    }

    void MeshRenderer::Begin(const Environment3D& env)
    {
#if 1
        glDisable(GL_CULL_FACE);
        glDepthMask(GL_TRUE);
        glEnable(GL_DEPTH_TEST);
        glDepthFunc(GL_LEQUAL);

        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

        // glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
#endif

        shader->Bind();

        // set uniforms
        glm::mat4 view = env.camera->getViewMatrix();
        glm::mat4 proj = env.camera->getProjectionMatrix(env.window_width, env.window_height);
        glm::mat4 vp = proj * view;
        shader->SetUniformMat4("vp", vp);
    }

    void MeshRenderer::End()
    {
        // do nothing.
        shader->Unbind();
    }

    void MeshRenderer::Draw(const Mesh& mesh)
    {
        mesh.Bind();
        // default model transform to avoid overwritting
        glm::mat4 model_transform = glm::mat4(1.0f);
        shader->SetUniformMat4("m", model_transform);
        uint32_t nindices = mesh.NumIndices();
        glDrawElements(GL_TRIANGLES, nindices, GL_UNSIGNED_SHORT, 0);
        mesh.Unbind();
    }

    void MeshRenderer::Draw(const Mesh& mesh, const glm::mat4& model_transform)
    {
        mesh.Bind();
        shader->SetUniformMat4("m", model_transform);
        uint32_t nindices = mesh.NumIndices();
        glDrawElements(GL_TRIANGLES, nindices, GL_UNSIGNED_SHORT, 0);
        mesh.Unbind();
    }
}
